<?php

namespace app\pay\logic;

use app\common\exception\BusinessException;
use app\common\model\MaterialFile;
use app\common\model\Order;
use app\common\model\User as UserModel;
use app\common\model\UserCourse;
use app\common\model\UserMaterial;
use app\common\model\UserVideoCollection;
use app\common\model\UserVip;
use app\common\model\UserVipCombo;
use app\common\model\VideoCollection;
use app\common\service\UserService;
use function app;

class PayCallback
{
    /**
     * invoke
     * @param $order_sn
     * @param $transaction_id
     * @throws BusinessException
     */
    public function invoke($order_sn, $transaction_id)
    {
        // 查询订单数据
        $model = app(Order::class);
        $where = [
            ['status', '=', 1],
            ['order_sn', '=', $order_sn],
        ];
        $orderInfo = $model->where($where)->find();
        if (!$orderInfo) {
            throw new BusinessException('未获取到订单信息');
        }

        // 初始化扩展参数
        $orderInfo['extend'] = json_decode($orderInfo['extend'], true);
        if (!$orderInfo['extend']) {
            throw new BusinessException('订单扩展信息获取失败');
        }

        // 提取参数
        $order_type = $orderInfo['order_type'];

        // 进行充值
        $model->startTrans();
        if ($order_type == 1) {
            $this->rechargeMember($orderInfo);
        } elseif ($order_type == 2) {
            $this->rechargeCourse($orderInfo);
        } elseif ($order_type == 3) {
            $this->rechargeMaterial($orderInfo);
        } elseif ($order_type == 4) {
            $this->rechargeVideoCollection($orderInfo);
        }

        // 更新订单
        $time = time();
        $isUpdate = $model->where($where)->save(
            [
                'status' => 4,
                'transaction_id' => $transaction_id,
                'p_time' => $time,
                's_time' => $time,
                'f_time' => $time,
                'u_time' => $time
            ]
        );
        if (!$isUpdate) {
            throw new BusinessException('更新订单失败');
        }

        // 标记白名单
        $userService = new UserService();
        $userService->setUserToWhitelist($orderInfo['user_id']);

        // 升级为代理商
        $userService->setUserToAgent($orderInfo['user_id']);

        // 提交事务
        $model->commit();
    }

    /**
     * 充值会员
     * @param $order
     * @throws
     */
    private function rechargeMember($order)
    {
        // 提取参数
        $vip_comb_id = $order['extend']['vip_comb_id'] ?? 0;
        $profession_id = $order['extend']['profession_id'] ?? 0;

        // 检查数据
        if (!$profession_id) {
            throw new BusinessException("订单扩展信息的专业获取失败");
        }

        // 查询套餐
        $vipCombInfo = app(UserVipCombo::class)->getInfoById($vip_comb_id);
        if (!$vipCombInfo) {
            throw new BusinessException('未获取套餐信息');
        }

        // 会员充值
        (new UserVip())->setExpire($order['user_id'], $profession_id, $vipCombInfo['expire'], $vipCombInfo['expire_type']);

        // 赠送积分
        if ($vipCombInfo['score'] > 0) {
            $userModel = new UserModel();
            $where = [['id', '=', $order['user_id']]];
            if (!$userModel->where($where)->inc('score', $vipCombInfo['score'])->update()) {
                throw new BusinessException('充值积分失败');
            }
        }
    }

    /**
     * 充值课程
     * @param $order
     * @throws BusinessException
     */
    private function rechargeCourse($order)
    {
        // 提取参数
        $course_id = $order['extend']['course_id'] ?? 0;

        // 检查数据
        if (!$course_id) {
            throw new BusinessException("订单扩展信息的课程id获取失败");
        }

        // 课程充值
        (new UserCourse())->setExpire($order['user_id'], $course_id);
    }

    /**
     * 充值资料
     * @param $order
     * @throws
     */
    private function rechargeMaterial($order)
    {
        // 提取参数
        $material_id = $order['extend']['material_id'] ?? 0;

        // 检查数据
        if (!$material_id) {
            throw new BusinessException("订单扩展信息的资料id获取失败");
        }

        // 查询信息
        $materialInfo = app(MaterialFile::class)->find($material_id);
        if (!$materialInfo) {
            throw new BusinessException('资料不存在');
        }

        // 资料充值
        $expire = 86400 * $materialInfo['expire'];
        (new UserMaterial())->setExpire($order['user_id'], $material_id, $expire);
    }

    /**
     * 充值网课
     * @param $order
     * @throws
     */
    private function rechargeVideoCollection($order)
    {
        // 提取参数
        $collection_id = $order['extend']['collection_id'] ?? 0;

        // 检查数据
        if (!$collection_id) {
            throw new BusinessException("订单扩展信息的视频合集编号获取失败");
        }

        // 查询信息
        $collectionInfo = app(VideoCollection::class)->find($collection_id);
        if (!$collectionInfo) {
            throw new BusinessException('视频合集不存在');
        }

        // 充值账户
        $expire = 86400 * 365;
        (new UserVideoCollection())->setExpire($order['user_id'], $collection_id, $expire);

        // 更新销售量
        app(VideoCollection::class)->updateSaleNum($collection_id);
    }
}
